package com.atguigu.dga.assessor.security;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.dga.assessor.Assessor;
import com.atguigu.dga.governance.bean.AssessParam;
import com.atguigu.dga.governance.bean.GovernanceAssessDetail;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.permission.FsPermission;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.math.BigDecimal;
import java.net.URI;
import java.util.ArrayList;

@Component("FILE_ACCESS_PERMISSION")
public class FileAccessPermissionAssessor extends Assessor {
    @Value("${hdfs.uri}")
    String hdfsUri;
    @Override
    public void checkProblem(GovernanceAssessDetail governanceAssessDetail, AssessParam assessParam) throws Exception {
        //获取参数
        String metricParamsJson = assessParam.getGovernanceMetric().getMetricParamsJson();
        JSONObject jsonObject = JSONObject.parseObject(metricParamsJson);
        String filePermission = jsonObject.getString("file_permission");
        String dirPermission = jsonObject.getString("dir_permission");

        //获取考评日期
        String assessDate = assessParam.getAssessDate();
        //获取owner
        String tableFsOwner = assessParam.getTableMetaInfo().getTableFsOwner();
        //获取文件路径
        String tableFsPath = assessParam.getTableMetaInfo().getTableFsPath();

        //获取当前目录下的内容
        FileSystem fs = FileSystem.get(new URI(hdfsUri), new Configuration(), tableFsOwner);
        FileStatus[] fileStatuses = fs.listStatus(new Path(tableFsPath));
        //保存越权的文件集合
        ArrayList<String> stringsPermission = new ArrayList<>();
        //遍历当前目录下的文件是否越权
        checkFileOrDirPermission(fileStatuses, fs, filePermission, dirPermission,stringsPermission);

        //如果存在越权
        if(stringsPermission.size()>0){
            governanceAssessDetail.setAssessScore(BigDecimal.ZERO);
            governanceAssessDetail.setAssessProblem("目录文件访问权限超过建议值");
            governanceAssessDetail.setAssessComment("权限越权文件为:" +stringsPermission);
        }

    }

    private void checkFileOrDirPermission(FileStatus[] fileStatuses, FileSystem fs, String filePermission, String dirPermission, ArrayList<String> stringsPermission) throws IOException {
        for (FileStatus fileStatus : fileStatuses) {
            if (fileStatus.isFile()){
                //判断权限
                Boolean isBeyond = checkPermission(fileStatus.getPermission(), filePermission);
                if (isBeyond){
                    //保存路径
                    stringsPermission.add(fileStatus.getPath().toString());
                }
            }else{
                //检查自身权限
                Boolean isBeyond = checkPermission(fileStatus.getPermission(), dirPermission);
                if (isBeyond){
                    //保存路径
                    stringsPermission.add(fileStatus.getPath().toString());
                }
                //取当前目录下的内容
                FileStatus[] fileStatuses1 = fs.listStatus(fileStatus.getPath());
                //下探
                checkFileOrDirPermission(fileStatuses1,fs,filePermission,dirPermission,stringsPermission);
            }

        }

    }

    private Boolean checkPermission(FsPermission fspermission, String permission) {
        //取权限标准
        Integer userRMX = Integer.parseInt(permission.charAt(0) + "");
        Integer groupRMX = Integer.parseInt(permission.charAt(1) + "");
        Integer otherRMX = Integer.parseInt(permission.charAt(2) + "");
        if (fspermission.getUserAction().ordinal()>userRMX){
            return true;
        }else if(fspermission.getGroupAction().ordinal()>groupRMX){
            return true;
        }else if (fspermission.getOtherAction().ordinal()>otherRMX){
            return true;
        }
        return false;
    }
}
